﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
using static STRobot.Form1;

namespace STRobot
{
    public partial class Form2 : Form
    {
        public float zoom_;
        public Form2()
        {
            InitializeComponent();
            zoom_ = GetHostDisplayResolutionScaleX();
        }
        private struct UiData
        {
            public string Name;
            public string ParentName;
            public uint address; //内存地址
            public uint ParentAddress;//父UI地址
            public Point pos; //父UI内坐标
            public Point RelativePos;//游戏窗口内相对坐标
            public Point Size; //大小
            public TreeNode treeNode; //控件节点;
        }
        private Cursor xxcursor;
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetCursorPos(ref Point p);

        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern IntPtr WindowFromPoint(Point p);

        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern IntPtr FindWindowW(string classname, string windowname);

        [DllImport("User32.dll")]
        public static extern IntPtr GetDC(IntPtr A_0);
        [DllImport("gdi32.dll")]
        public static extern int GetDeviceCaps(IntPtr A_0, int A_1);
        [DllImport("User32.dll")]
        public static extern IntPtr ReleaseDC(IntPtr A_0, IntPtr A_1);

        public static float GetHostDisplayResolutionScaleX()
        {
            IntPtr dC = GetDC(IntPtr.Zero);
            float horizontalDPI = GetDeviceCaps(dC, 0x58);
            float verticalDPI = GetDeviceCaps(dC, 0x5A);

            float dpi = (horizontalDPI + verticalDPI) / 2;
            float dDpi = 1 + ((dpi - 96) / 24) * 0.25f;
            if (dDpi < 1)
            {
                dDpi = 1;
            }
            ReleaseDC(IntPtr.Zero, dC);
            return dDpi;
        }
        IntPtr gameHwnd_;
        private void showRectInDesktop(ref Rectangle rect, IntPtr hWnd)
        {
            RECT re1 = new RECT();
            RECT re2 = new RECT();
            GetWindowRect(gameHwnd_, ref re1);
            GetClientRect(gameHwnd_, ref re2);
            //取得标题栏的高度
            var re = new RECT();
            re.Left = re1.Right - re2.Right;
            re.Top = re1.Bottom - re2.Bottom;
            Graphics graphics = Graphics.FromHwnd((IntPtr)hWnd);
            Pen pen = new Pen(Brushes.Red, 5);
            Brush brush = new SolidBrush(Color.Red);
            graphics.DrawRectangle(pen, rect);

        }
        List<UiData> lists = new List<UiData>();
        private void button18_Click(object sender, EventArgs e)
        {
            treeView1.Nodes.Clear();
            lists.Clear();
            string title = "神途-" + Config.Get().servername + "-" + Config.Get().rolename;
            gameHwnd_ = FindWindowW("GAME", title);
            if ((Int32)gameHwnd_ == 0 && this.textBox1.Text.Length > 0)
            {
                string str = this.textBox1.Text.Substring(2, this.textBox1.Text.Length - 2);
                gameHwnd_ = (IntPtr)Convert.ToInt32(str, 16);
            }
            this.textBox1.Text = "0x" + Convert.ToString((uint)gameHwnd_, 16);
            if (StDll.Initst(gameHwnd_) == 1)
            {
                lists.Clear();
                StDll.ShowGameAllUi((uint parent, string parentuiname, uint address, string uiname, Point pos, Point relativePos, Point size) => {

                    TreeNode treeNode = new TreeNode();
                    treeNode.Tag = this;
                    treeNode.ImageIndex = 0;

                    treeNode.Text = "["+ Convert.ToString(address, 16) + "]" + uiname + "(" + relativePos.x.ToString() + "," + relativePos.y.ToString() + "  " + pos.x.ToString() + "," + pos.y.ToString() + " size:" + size.x.ToString() + "," + size.y.ToString() + ")";
                    bool isexistparent = false;
                    UiData ui = new UiData();
                    ui.Name = uiname;
                    ui.ParentName = parentuiname;
                    ui.address = address;
                    ui.ParentAddress = parent;
                    ui.pos = pos;
                    ui.RelativePos = relativePos;
                    ui.Size = size;
                    ui.treeNode = treeNode;
                    //MessageBox.Show(uiname);
                    foreach (var uidata in lists)
                    {
                        if (uidata.Name == parentuiname) //已经父存在
                        {
                            //在父基础上添加
                            isexistparent = true;
                            uidata.treeNode.Nodes.Add(treeNode);
                            break;
                        }
                    }
                    if (!isexistparent)
                    {
                        treeView1.Nodes.Add(treeNode);
                    }
                    lists.Add(ui);
                    //treeView1.it
                });
                if (lists.Count > 0)
                {
                    lists[0].treeNode.Expand();
                }
            }
            // public delegate void showalluicallback(uint parent, string parentuiname, uint address, string uiname, Point pos, Point relativePos, Point size);

        }
        public struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetWindowRect(IntPtr hWnd, ref RECT rect);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetClientRect(IntPtr hWnd, ref RECT rect);
        private void button19_Click(object sender, EventArgs e)
        {
            if (gameHwnd_ != IntPtr.Zero)
            {
                RECT re = new RECT();

                foreach (var item in lists)
                {
                    if (item.treeNode == treeView1.SelectedNode)
                    {
                        var index = treeView1.SelectedNode.Index;
                        var pos = item.pos;
                        re.Left = pos.x;
                        re.Top = pos.y;
                        Rectangle rect = new Rectangle(re.Left, re.Top, item.Size.x, item.Size.y);
                        showRectInDesktop(ref rect, gameHwnd_);
                        textBox6.Text = "[" + Convert.ToString(item.address, 16) + "]" + item.Name;
                        textBox7.Text = item.ParentName;
                        textBox8.Text = pos.x.ToString() + "," + pos.y.ToString() + " size:" + item.Size.x.ToString() + "," + item.Size.y.ToString();
                    }
                }
            }
        }

        private void button17_Click(object sender, EventArgs e)
        {
            if (StDll.Initst((IntPtr)0) == 1)
            {
                // MessageBox.Show("神途初始化成功");
                listView1.Items.Clear();
                StringBuilder buf = new StringBuilder(40960);
                buf.Append("test");
                var len = StDll.GetAllObjectFromString(buf);
                var str = buf.ToString();
                var monsterlist = str.Split('|');
                int id = 1;
                foreach (var item in monsterlist)
                {
                    if (item.Length == 0)
                    {
                        continue;
                    }
                    var monster = item.Split(',');
                    ListViewItem it = new ListViewItem();
                    it.Text = id.ToString();
                    foreach (var i in monster)
                    {
                        it.SubItems.Add(i);
                    }

                    listView1.Items.Add(it);
                    id++;
                }
            }
            else
            {
                MessageBox.Show("神途初始化失败");
            }
        }
        public struct UiInfo
        {
            public RECT rect;
            public String parentName;
            public String uiName;
        }
        public void SetCursor(Bitmap cursor, Point hotPoint)
        {
            int hotX = hotPoint.x;
            int hotY = hotPoint.y;
            Bitmap myNewCursor = new Bitmap(cursor.Width * 2 - hotX, cursor.Height * 2 - hotY);
            Graphics g = Graphics.FromImage(myNewCursor);
            g.Clear(Color.FromArgb(0, 0, 0, 0));
            g.DrawImage(cursor, cursor.Width - hotX, cursor.Height - hotY, cursor.Width,
            cursor.Height);

            this.Cursor = new Cursor(myNewCursor.GetHicon());

            g.Dispose();
            myNewCursor.Dispose();
        }

        private void listView1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (listView1.SelectedIndices != null && listView1.SelectedIndices.Count > 0)
            {
                // **获取行号**
                int nRow = listView1.Items[listView1.SelectedIndices[0]].Index;

                // 鼠标点转换客户区域坐标
                System.Drawing.Point point = new System.Drawing.Point(MousePosition.X, MousePosition.Y);
                System.Drawing.Point m_MBRpt = listView1.PointToClient(point);
                // 获取列
                ListViewItem lvi = listView1.GetItemAt(m_MBRpt.X, m_MBRpt.Y);
                if (lvi != null)
                {
                    ListViewItem.ListViewSubItem lvsi = lvi.GetSubItemAt(m_MBRpt.X, m_MBRpt.Y);
                    // **获取列号**
                    int colIndex = lvi.SubItems.IndexOf(lvsi);
                    var content = listView1.Items[listView1.SelectedIndices[0]].SubItems[colIndex].Text;
                    Clipboard.SetText(content);
                    MessageBox.Show("[" + content + "]复制成功");
                }
            }
        }

        //拖动选择UI操作
        private void button20_MouseCaptureChanged(object sender, EventArgs e)
        {
            this.Cursor = xxcursor;
        }
        private void button20_MouseUp(object sender, MouseEventArgs e)
        {
            this.Cursor = xxcursor;
        }
        private void button20_MouseMove(object sender, MouseEventArgs e)
        {
            RECT re1 = new RECT();
            RECT re2 = new RECT();
            string name = "";
            string pname = "";

            if (gameHwnd_ != IntPtr.Zero)
            {
                RECT re = new RECT();
                RECT uipos = new RECT();
                GetWindowRect(gameHwnd_, ref re1);
                GetClientRect(gameHwnd_, ref re2);
                //取得标题栏的高度
                re.Left = re1.Right - re2.Right;
                re.Top = re1.Bottom - re2.Bottom;
                re.Left = (int)(re.Left / zoom_); //处理缩放
                re.Top = (int)(re.Top / zoom_);


                Point mspoint = new Point();
                //GetCursorPos(ref mspoint);

                mspoint.x = Cursor.Position.X;
                mspoint.y = Cursor.Position.Y;
                var wnd = WindowFromPoint(mspoint);
                if (wnd != gameHwnd_) return;
                mspoint.x += 15;
                mspoint.y += 15;
                mspoint.x = (int)(mspoint.x / zoom_);//处理缩放
                mspoint.y = (int)(mspoint.y / zoom_);
                Rectangle rect = new Rectangle();
                List<UiInfo> rects = new List<UiInfo>();
                StDll.ShowGameAllUi((uint parent, string parentuiname, uint address, string uiname, Point pos, Point relativePos, Point size) =>
                {
                    if (size.x > 0 && size.y > 0)
                    {
                        //收集所有满足条件的窗口位置，然后再从中取一个离鼠标位置最近的
                        Rectangle cre = new Rectangle(re.Left + pos.x, re.Top + pos.y, size.x, size.y);
                        if (mspoint.x < cre.Right && mspoint.x > cre.Left && mspoint.y < cre.Bottom && mspoint.y > cre.Top)
                        {
                            RECT rr = new RECT();
                            rr.Left = pos.x;
                            rr.Top = pos.y;
                            rr.Right = size.x;
                            rr.Bottom = size.y;
                            UiInfo uiInfo = new UiInfo();
                            uiInfo.rect = rr;
                            uiInfo.parentName = parentuiname;
                            uiInfo.uiName = uiname;
                            rects.Add(uiInfo);
                        }
                    }
                });
                UiInfo minInfo = new UiInfo();
                minInfo.rect = new RECT();
                foreach (var item in rects)
                {
                    //选一个离鼠标位置最近的矩形，用来显示
                    if (item.rect.Left > minInfo.rect.Left && item.rect.Top > minInfo.rect.Top)
                    {
                        minInfo = item;
                    }
                }
                {
                    //rect.X = re.Left + pos.x;
                    //rect.Y = re.Top + pos.y;
                    rect.X = minInfo.rect.Left;
                    rect.Y = minInfo.rect.Top;
                    rect.Width = minInfo.rect.Right;
                    rect.Height = minInfo.rect.Bottom;
                    name = minInfo.uiName;
                    pname = minInfo.parentName;
                    //uipos.Left = pos.x;
                    //uipos.Top = pos.y;
                    //uipos.Right = size.x;
                    //uipos.Bottom = size.y;
                }
                var str = uipos.Left.ToString() + "," + uipos.Top.ToString();
                textBox6.Text = name;
                textBox7.Text = pname;
                textBox8.Text = str;
                showRectInDesktop(ref rect, gameHwnd_);
            }
        }

        private void button20_MouseDown(object sender, MouseEventArgs e)
        {
            //Capture = true;
            xxcursor = Cursor;
            Bitmap a = (Bitmap)Bitmap.FromFile("movies-alt.png");
            SetCursor(a, new Point(0, 0));
        }

        private void textBox9_KeyDown(object sender, KeyEventArgs e)
        {
            textBox9.Text = e.KeyValue.ToString();
            e.Handled = true;
        }

        private void textBox9_KeyPress(object sender, KeyPressEventArgs e)
        {
            e.Handled = true;
        }


        //拖动选择其他游戏窗口
        [DllImport("user32.dll")]
        public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
       
        [DllImport("user32.dll")]
        public static extern int GetClassName(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
        private void button1_MouseCaptureChanged(object sender, EventArgs e)
        {
            this.Cursor = xxcursor;
        }

        private void button1_MouseDown(object sender, MouseEventArgs e)
        {
            xxcursor = Cursor;
            Bitmap a = (Bitmap)Bitmap.FromFile("movies-alt.png");
            SetCursor(a, new Point(0, 0));
        }

        private void button1_MouseMove(object sender, MouseEventArgs e)
        {

        }

        private void button1_MouseUp(object sender, MouseEventArgs e)
        {
            //获取鼠标所在窗口句柄，并判断是否游戏窗口
            int x = Cursor.Position.X;
            int y = Cursor.Position.Y;
            Point p = new Point(x, y);
            IntPtr formHandle = WindowFromPoint(p);
            StringBuilder cllassName = new StringBuilder();
            GetClassName(formHandle, cllassName, cllassName.Capacity);
            this.textBox1.Text = "";
            if (cllassName.ToString() == "GAME")
            {
                this.textBox1.Text = "0x" + Convert.ToString((uint)formHandle, 16);
            }
            
            
            this.Cursor = xxcursor;
        }
    }
}
